using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using VISTEN.APP.Data;
using System.Text.RegularExpressions;

namespace GR_AutoCode_Design
{
    public partial class MainFrm : Form
    {
        public MainFrm()
        {
            InitializeComponent();
            TbxDBStr.Text=@"server=.\sqlexpress;uid=sa;pwd=sasa;database=master";
        }
        string _Author_Area_Code = @"/********************************
* AUTO-Generation
* 代码自动生成
* 作者: VISTEN
* 模板路径：@(TempPath)
* 日期：@(DateTime)
* 说明：
*********************************/";
        DBHelper _db = null;
        private void BtnLinkDB_Click(object sender, EventArgs e)
        {
            _db = new DBHelper(TbxDBStr.Text);
            DataTable table_dt = _db.ExecuteDataTable(_db.GetSqlStringCommond("select [id], [name] from [sysobjects] where [type] = 'u' order by [name]"));
            listView1.Items.Clear();
            foreach (DataRow item in table_dt.Rows)
            {
                ListViewItem lv = new ListViewItem();
                lv.SubItems[0].Text = item["name"].ToString();
                listView1.Items.Add(lv);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            OpenFileDialog of = new OpenFileDialog();
            of.Filter = "模板文件|*.cstemp";
            if (of.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                TbxModel.Text = of.FileName;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (TbxModel.Text.Length > 0 && listView1.SelectedItems.Count>0)
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    CreateCode(fbd.SelectedPath);
                }
            }
        }

        private void CreateCode(string path)
        {
            using (StreamReader sr = new StreamReader(TbxModel.Text))
            {
                #region @.author 代码处理
                string temp = _Author_Area_Code + "\r\n" + sr.ReadToEnd();
                #endregion
                foreach (ListViewItem item in listView1.SelectedItems)
                {
                    string codeTemp = temp;
                    var className = item.SubItems[0].Text;
                    var classNameEntity = className + "Entity";

                    var dateTime = DateTime.Now.ToString();
                    var pk = "";

                    #region sql

                    //查询列，对Create 和 Update 赋值
                    string sql = @"
SELECT 
    表名=case when a.colorder=1 then d.name else '' end, 
    字段名=a.name, 
    标识=COLUMNPROPERTY(a.id,a.name,'IsIdentity'),
    主键=case when exists(SELECT 1 FROM sysobjects where xtype= 'PK' and name in ( 
SELECT name FROM sysindexes WHERE indid in( 
SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid 
))) then '1' else '' end, 
    类型=b.name, 
    占用字节数=a.length, 
    长度=COLUMNPROPERTY(a.id,a.name, 'PRECISION'), 
    小数位数=isnull(COLUMNPROPERTY(a.id,a.name, 'Scale'),0), 
    允许空=case when a.isnullable=1 then '√'else '' end, 
    默认值=isnull(e.text, ''), 
    字段说明=isnull(g.[value], '') 
FROM syscolumns a 
    left join systypes b on a.xtype=b.xusertype 
    inner join sysobjects d on a.id=d.id and d.xtype= 'U' and d.name <> 'dtproperties' and d.name = '" + className + @"'
    left join syscomments e on a.cdefault=e.id 
    left join sys.extended_properties g on a.id=g.major_id and a.colid=g.minor_id and g.name='MS_Description' 
order by a.id,a.colorder ";

                    #endregion
                    DataTable table_dt = _db.ExecuteDataTable(_db.GetSqlStringCommond(sql));


                    #region 获得主键
                    foreach (DataRow item_Row in table_dt.Rows)
                    {
                        if (item_Row[3].ToString().Equals("1"))
                        {
                            pk = item_Row[1].ToString();
                        }
                    }
                    #endregion

                    using (StreamWriter sw = new StreamWriter(path +"\\"+ classNameEntity + ".cs", false))
                    {

                        //获得要遍历的代码体

                        #region @.for 代码处理
                        Regex regexFor = new Regex(@"@(\.for)\{[^\}]+[\}{1}]");
                        MatchCollection regexForResults = regexFor.Matches(temp);
                        foreach (Match item_Regex in regexForResults)
                        {
                            //生成遍历体代码
                            StringBuilder setCodeArea = new StringBuilder();
                            var regexForResult_code = new Regex(@"\{[^\}]+\}").Match(item_Regex.Value).Value.Replace('{', ' ').Replace('}', ' ');
                            if (regexForResult_code.Length > 0)
                            {
                                foreach (DataRow item_Row in table_dt.Rows)
                                {
                                    var row_db_type = item_Row[4].ToString();
                                    var row_db_desc = item_Row[10].ToString();
                                    if (!item_Row[1].ToString().Equals(pk))
                                    {

                                        setCodeArea.Append("\t\t\t");
                                        setCodeArea.Append(regexForResult_code
                                            .Replace("@.Propertity", item_Row[1].ToString())
                                            .Replace("@.Description", item_Row[10].ToString())
                                            .Replace("@.DataType", item_Row[4].ToString())
                                            );
                                        setCodeArea.Append("\r\n");
                                    }
                                }
                                codeTemp = codeTemp.Replace(item_Regex.Value, setCodeArea.ToString());
                            }
                        }

                        #endregion

                        #region  @(Key) 关键字处理
                        //将列表中的关键字 做替换处理
                        Regex r_Key = new Regex("^@.[A-Za-z]+$");
                        foreach (ListViewItem item_key in listView2.Items)
                        {
                            //属性
                            var result = r_Key.Match(item_key.SubItems[1].Text).Value;
                            if (result.Length > 0)
                            {
                                result = result.Replace("@.", "");
                                /*
                                 * TableName ClassName
                                 * DateTime
                                 * Pk
                                 * TableName
                                 */
                                switch (result)
                                {
                                    case "TableName":
                                        codeTemp = codeTemp.Replace(item_key.SubItems[0].Text, item_key.SubItems[2].Text + className + item_key.SubItems[3].Text);
                                        break;
                                    case "ClassName":
                                        codeTemp = codeTemp.Replace(item_key.SubItems[0].Text, item_key.SubItems[2].Text + className + item_key.SubItems[3].Text);
                                        break;
                                    case "DateTime":
                                        codeTemp = codeTemp.Replace(item_key.SubItems[0].Text, item_key.SubItems[2].Text + DateTime.Now.ToString() + item_key.SubItems[3].Text);
                                        break;
                                    case "Pk":
                                        codeTemp = codeTemp.Replace(item_key.SubItems[0].Text, item_key.SubItems[2].Text + pk + item_key.SubItems[3].Text);
                                        break;
                                    default:
                                        break;
                                }
                            }
                            //值
                            else
                            {
                                codeTemp = codeTemp.Replace(item_key.SubItems[0].Text, item_key.SubItems[2].Text + item_key.SubItems[1].Text + item_key.SubItems[3].Text);
                            }
                        }

                        #endregion

                        sw.Write(codeTemp);
                    }
                }
            }
        }

        private void MainFrm_Load(object sender, EventArgs e)
        {
            listView1.Columns.Add("表名",listView1.Width);

            listView2.Columns.Add("Key", 130);
            listView2.Columns.Add("Value", 130);
            listView2.Columns.Add("Prefix", 50);
            listView2.Columns.Add("Suffix", 50);
            ListViewItem item;
            item = new ListViewItem();
            item.SubItems[0].Text = "@(Namespace)";
            item.SubItems.Add("VISTEN.APP");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);
            item = new ListViewItem();
            item.SubItems[0].Text = "@(Model)";
            item.SubItems.Add("VISTEN.APP.Model");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);
            item = new ListViewItem();
            item.SubItems[0].Text = "@(EntityModel)";
            item.SubItems.Add("VISTEN.APP.EntityModel");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);
            item = new ListViewItem();
            item.SubItems[0].Text = "@(ClassNameEntity)";
            item.SubItems.Add("@.ClassName");
            item.SubItems.Add("");
            item.SubItems.Add("Entity");
            listView2.Items.Add(item);
            item = new ListViewItem();
            item.SubItems[0].Text = "@(ClassName)";
            item.SubItems.Add("@.ClassName");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);
            item = new ListViewItem();
            item.SubItems[0].Text = "@(Author)";
            item.SubItems.Add("VISTEN");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);
            item = new ListViewItem();
            item.SubItems[0].Text = "@(DateTime)";
            item.SubItems.Add("@.DateTime");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);
            item = new ListViewItem();
            item.SubItems[0].Text = "@(PK)";
            item.SubItems.Add("@.Pk");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);

        }

        private void BtnNewPropertity_Click(object sender, EventArgs e)
        {
            ListViewItem item;
            item = new ListViewItem();
            item.SubItems[0].Text = "@(KeyWord)";
            item.SubItems.Add("");
            item.SubItems.Add("");
            item.SubItems.Add("");
            listView2.Items.Add(item);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (listView2.SelectedItems.Count>0)
            {
                listView2.Items.Remove(listView2.SelectedItems[0]);
            }
        }

        ListViewItem _SelectedItem;
        private void listView2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView2.SelectedItems.Count > 0)
            {
                ListViewItem item = listView2.SelectedItems[0];
                _SelectedItem = item;
                TbxKey.Text = item.SubItems[0].Text;
                TbxValue.Text = item.SubItems[1].Text;
                TbxPrefix.Text = item.SubItems[2].Text;
                TbxSuffix.Text = item.SubItems[3].Text;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            _SelectedItem.SubItems[0].Text = TbxKey.Text;
            _SelectedItem.SubItems[1].Text = TbxValue.Text;
            _SelectedItem.SubItems[2].Text = TbxPrefix.Text;
            _SelectedItem.SubItems[3].Text = TbxSuffix.Text;
        }

    }
}
